package work.xiaohong.saolei.websocket;

/**
 * 由于是websocket 所以原本是@RestController的http形式
 * 直接替换成@ServerEndpoint即可，作用是一样的 就是指定一个地址
 * 表示定义一个websocket的Server端
 * 这里的服务地址为：ws://localhost:18090/chatCentre/{userId}
 */

import com.alibaba.fastjson.JSONObject;
import work.xiaohong.saolei.controller.PkController;
import work.xiaohong.saolei.pojo.SendMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author : xiaohong
 * @date : 2021/4/14 8:30
 * 中央聊天WebSocket
 */

@ServerEndpoint("/ws/pkCentre/{id}")
@Component
public class PkCentre {

    //将所有客户端对象储存到Map集合中
    public static Map<Long, PkCentre> chatCentreClients = new ConcurrentHashMap<>();
    // 下面两个必须是private，上面用来储存的map只能获取到其长度，其内容直接获取为null
    //会话
    public Session session;
    //会话唯一标识，使用openId来确定唯一的
    private String openId;

    @Autowired
    private PkController pkController;



    /**
     * 建立连接成功调用
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") Long id, Session session) {
        // 保存当前连接信息
        this.session = session;
        chatCentreClients.put(id,this);
        System.out.println("连接成功！");
        System.out.println("当前已连接数"+chatCentreClients.size());
        System.out.println(chatCentreClients);
    }

    /**
     * 关闭连接时调用
     * @param session
     */
    @OnClose
    public void onClose(@PathParam("id") Long id,Session session) {
        chatCentreClients.remove(id);
        System.out.println("关闭连接！");
        System.out.println("当前剩余连接数"+chatCentreClients.size());
        System.out.println(chatCentreClients);
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        // message是一个json
        // 将message进行反序列化
        SendMsg msg = JSONObject.parseObject(message, SendMsg.class);
        System.out.println(msg);
        // 判断是否是心跳消息
        if (!msg.getHeart()) {
//            System.out.println("心跳消息：" + msg.getStart());
            try {
                //将信息返回到指定用户的页面中
                sendMessageTo(message,Long.parseLong(msg.getReceiver()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            try {
//                List<MqMsg> unCallMessageList = chatCentreController.pullNack(msg.getTo()).getData();
                //将未读信息返回到指定用户的页面中
                sendMessageTo(message,Long.parseLong(msg.getSender()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("连接异常:"+throwable);
    }



    /**
     * 向指定的客户端发送数据
     * @param message 推送的信息
     * @param to 接收者
     */
    public static Boolean sendMessageTo(String message, Long to) throws IOException {
        // 判断接收者状态
        Boolean result = false;
        try {
            if (chatCentreClients.get(to) != null){
                chatCentreClients.get(to).session.getBasicRemote().sendText(message);
                result = true;
            }else {
                result = false;
            }
        } catch (IOException e) {
            result = false;
            e.printStackTrace();
        }

        return result;

    }

    /**
     * 返回指定对象状态 0 离线 1 在线 2 用户不存在
     * @param cid
     * @return
     */
    public Integer userState(Long cid){
        if (chatCentreClients.get(cid) != null){
            PkCentre webSocketCentre = chatCentreClients.get(cid);
            if(!webSocketCentre.session.isOpen()){
                return 0;
            }else {
                return  1;
            }
        }else {
            return 2;
        }
    }

    /**
     * 给所有用户进行推送信息
     * @param message 推送的信息
     */
    public void sendMessageAll(String message) throws IOException {
        for (PkCentre item : chatCentreClients.values()) {
            item.session.getBasicRemote().sendText(message);
        }
    }

}
